package com.msun.auth.utils;

import cn.hutool.core.text.CharSequenceUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;

@Slf4j
public final class LogUtils {

    private static final String PKG_NAME = "com.msun.auth";
    public static void mixInfo(Object... args) {
        if (args == null || args.length == 0) return;
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        String lastStack = null;
        if (stack.length >= 2) {
            StackTraceElement ele = stack[2];
            if (ele.getClassName().startsWith(PKG_NAME)) {
                lastStack = CharSequenceUtil.format("\n日志调用位置 -> class: {}\t method: {}\t line: {}\t\n", ele.getClassName(), ele.getMethodName(), ele.getLineNumber());
            }
        }
        ArrayList<String> arr = new ArrayList<>();
        for (int i = 0; i < args.length; i++) {
            arr.add(i + "、" + args[i]);
        }
        log.info("\n多行日志信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{}{}\n多行日志信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", lastStack, String.join("\n", arr));
    }

    public static void info(Object args) {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        String lastStack = null;
        if (stack.length >= 2) {
            StackTraceElement ele = stack[2];
            if (ele.getClassName().startsWith(PKG_NAME)) {
                lastStack = CharSequenceUtil.format("\n日志调用位置 -> class: {}\t method: {}\t line: {}\t\n", ele.getClassName(), ele.getMethodName(), ele.getLineNumber());
            }
        }
        log.info("\n日志信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n{}日志内容-> {}\n日志信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", lastStack, args);
    }

    public static void apiInfo(String api, Object args, Object dto, Object ctx) {
        log.info("\n日志信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n api -> {}\n args -> {}\n dto -> {}\n ctx -> {}\n日志信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", api, args, dto, ctx);
    }

    public static void apiErr(String api, Object args, Throwable e, Object ctx) {
        ArrayList<String> stackList = null;
        if (e != null) {
            stackList = new ArrayList<>();
            for (int i = 0; i < e.getStackTrace().length; i++) {
                StackTraceElement ele = e.getStackTrace()[i];
                if (ele.getClassName().startsWith(PKG_NAME)) {
                    stackList.add(CharSequenceUtil.format("\n\t stack{} -> class:{}  file:{}  method:{}  line:{}", i + 1, ele.getClassName(), ele.getFileName(), ele.getMethodName(), ele.getLineNumber()));
                }
            }
        }
        log.error("\n 错误日志信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n api -> {}\n args -> {}\n errorInfo -> {}\n ctx -> {}\n 报错调用链路: {}\n 错误日志信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", api, args, e != null ? e.getMessage() : null, ctx, stackList);
    }

    public static void exceptionErr(Object args, Throwable e, Object ctx) {
        ArrayList<String> stackList = null;
        if (e != null) {
            stackList = new ArrayList<>();
            for (int i = 0; i < e.getStackTrace().length; i++) {
                StackTraceElement ele = e.getStackTrace()[i];
                if (ele.getClassName().startsWith(PKG_NAME)) {
                    stackList.add(CharSequenceUtil.format("\n\t stack{} -> class:{}  file:{}  method:{}  line:{}", i + 1, ele.getClassName(), ele.getFileName(), ele.getMethodName(), ele.getLineNumber()));
                }
            }
        }
        log.error("\n 错误日志信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n jojo -> {}\n errorInfo -> {}\n ctx -> {}\n 报错调用链路: {}\n 错误日志信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", args, e != null ? e.getMessage() : null, ctx, stackList);
    }

    public static void sdkErr(String prefix, Throwable e, Object... args) {
        ArrayList<String> stackList = null;
        if (e != null) {
            stackList = new ArrayList<>();
            for (int i = 0; i < e.getStackTrace().length; i++) {
                StackTraceElement ele = e.getStackTrace()[i];
                if (ele.getClassName().startsWith(PKG_NAME)) {
                    stackList.add(CharSequenceUtil.format("\n\t stack{} -> class:{}  file:{}  method:{}  line:{}", i + 1, ele.getClassName(), ele.getFileName(), ele.getMethodName(), ele.getLineNumber()));
                }
            }
        }
        log.error("\n {}报错信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n errorInfo -> {}\n args -> {}\n 报错调用链路: {}\n {}报错信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", prefix, e != null ? e.getMessage() : null, Arrays.asList(args), stackList, prefix);
    }

    public static void printErr(Throwable e) {
        if (e == null) return;
        ArrayList<String> stackList = new ArrayList<>();
        for (int i = 0; i < e.getStackTrace().length; i++) {
            StackTraceElement ele = e.getStackTrace()[i];
            if (ele.getClassName().startsWith(PKG_NAME)) {
                stackList.add(CharSequenceUtil.format("\n\t stack{} -> class:{}  file:{}  method:{}  line:{}", i + 1, ele.getClassName(), ele.getFileName(), ele.getMethodName(), ele.getLineNumber()));
            }
        }
        log.error("\n报错信息START：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n errorInfo -> {}\n报错调用链路 -> {}\n报错信息END：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",e.getMessage(), stackList);
    }
}
